#pragma once

#include "stdafx.h"

#include "Scintilla.h"
#include "Notepad_plus_msgs.h"
#include "menuCmdID.h"

class CSciWindow :
	public ATL::CWindow
{
public:
	CSciWindow(HWND hScintillaWnd)
	{
		m_hWnd = hScintillaWnd;
		ATL_CHECK_HWND(m_hWnd);
	}

	CSciWindow(const NppData& nppData)
	{
		// Get the current scintilla
		int which = -1;
		::SendMessage(nppData._nppHandle, NPPM_GETCURRENTSCINTILLA, 0, (LPARAM)&which);
		if (which == -1)
			return;
		m_hWnd = (which == 0) ? nppData._scintillaMainHandle : nppData._scintillaSecondHandle;
		ATL_CHECK_HWND(m_hWnd);
	}

public:
	// Replaces all the text in the document with the zero terminated text string you pass in.
	void SetText(const CString& text)
	{
		CW2A atext(text);
		SendMessage(SCI_SETTEXT,NULL,(LPARAM)(LPSTR)atext);
	}

	int GetTextLength()
	{
		return SendMessage(SCI_GETTEXTLENGTH);
	}

	void SetSel(int anchorPos, int currentPos)
	{
		SendMessage(SCI_SETSEL,(WPARAM)anchorPos,(LPARAM)currentPos);
	}

	void ScrollCaret()
	{
		SendMessage(SCI_SCROLLCARET);
	}

	//void SetReadonly(bool isReadonly)
	//{
	//	SendMessage(SCI_SETREADONLY,(WPARAM)TRUE);
	//}

	//void SetPythonLangStyle()
	//{
	//	char pylang[] = "python";
	//	SendMessage(SCI_SETLEXERLANGUAGE,0,(LPARAM)pylang);
	//}

	int GetLineCount()
	{
		return SendMessage(SCI_GETLINECOUNT);
	}

	int GetCurrentPos()
	{
		return SendMessage(SCI_GETCURRENTPOS);
	}

	int LineFromPosition(int pos)
	{
		return SendMessage(SCI_LINEFROMPOSITION,(WPARAM)pos);
	}

	int PositionFromLine(int line)
	{
		return SendMessage(SCI_POSITIONFROMLINE,(WPARAM)line);
	}

	int GetLineEndPosition(int line)
	{
		return SendMessage(SCI_GETLINEENDPOSITION,(WPARAM)line);
	}

	int CopyRange(int start, int end)
	{
		return SendMessage(SCI_COPYRANGE,(WPARAM)start,(LPARAM)end);
	}

	void CopyCurrentLineContent()
	{
		int line = GetCurLineNum();
		int start = PositionFromLine(line);
		int end = GetLineEndPosition(line);
		CopyRange(start,end);
	}

	int GetCurLineNum()
	{
		int pos = GetCurrentPos();
		return LineFromPosition(pos);
	}

	void SelectCurLine()
	{
		int lineNum = GetCurLineNum();
		int start = PositionFromLine(lineNum);
		int end = PositionFromLine(lineNum+1);
		SetSelectionStart(start);
		SetSelectionEnd(end);
	}

	int LineLength(int lineNum)
	{
		return SendMessage(SCI_LINELENGTH,(WPARAM)lineNum);
	}

	ATL::CString GetLine(int lineNum)
	{
		int lineLength = LineLength(lineNum);
		char* pBuffer = new char[lineLength+1];
		int charCount = SendMessage(SCI_GETLINE,(WPARAM)lineNum,(LPARAM)pBuffer);
		pBuffer[lineLength] = '\0';
		ATL::CA2W lineText(pBuffer, CP_UTF8);
		return ATL::CString((LPCTSTR)lineText);
	}

	int GetCurLine(ATL::CString& lineText)
	{
		return 0;
	}

	void SetTargetStart(int pos)
	{
		SendMessage(SCI_SETTARGETSTART,(WPARAM)pos);
	}

	int GetTargetStart()
	{
		int targetStart = SendMessage(SCI_GETTARGETSTART);
		return targetStart;
	}

	void SetTargetEnd(int pos)
	{
		SendMessage(SCI_SETTARGETEND,(WPARAM)pos);
	}

	int GetTargetEnd()
	{
		int targetEnd = SendMessage(SCI_GETTARGETEND);
		return targetEnd;
	}

	int ReplaceTarget(const ATL::CString& text)
	{
		ATL::CW2A str(text, CP_UTF8);
		int pos = SendMessage(SCI_REPLACETARGET,(WPARAM)(-1),(LPARAM)(LPCSTR)str);
		return pos;
	}

	void InsertText(int pos, const ATL::CString& text)
	{
		ATL::CW2A str(text, CP_UTF8);
		SendMessage(SCI_INSERTTEXT,(WPARAM)pos,(LPARAM)(LPCSTR)str);
	}

	int GetSelectionStart()
	{
		return SendMessage(SCI_GETSELECTIONSTART);
	}

	int GetSelectionEnd()
	{
		return SendMessage(SCI_GETSELECTIONEND);
	}

	void SetSelectionStart(int pos)
	{
		SendMessage(SCI_SETSELECTIONSTART,(WPARAM)pos);
	}

	void SetSelectionEnd(int pos)
	{
		SendMessage(SCI_SETSELECTIONEND,(WPARAM)pos);
	}

	bool IsSelectionEmpty()
	{
		int start = GetSelectionStart();
		int end = GetSelectionEnd();
		return (start == end);
	}

	int GetDocumentEndPosition()
	{
		int lineCount = GetLineCount();
		int endPosition = GetLineEndPosition(lineCount-1);
		return endPosition;
	}

	void SetSearchFlags(int flags)
	{
		SendMessage(SCI_SETSEARCHFLAGS,(WPARAM)flags);
	}

	int GetSearchFlags()
	{
		int flags = SendMessage(SCI_GETSEARCHFLAGS);
		return flags;
	}

	int SearchInTarget(const ATL::CString& text)
	{
		ATL::CW2A str(text, CP_UTF8);
		int length = text.GetLength();
		int pos = SendMessage(SCI_SEARCHINTARGET,(WPARAM)length,(LPARAM)(LPCSTR)str);
		return pos;
	}

	void Copy()
	{
		SendMessage(SCI_COPY);
	}

	void CopyAllowLine()
	{
		SendMessage(SCI_COPYALLOWLINE);
	}

	void Cut()
	{
		SendMessage(SCI_CUT);
	}

	void CutLine()
	{

	}

private:
};


class CNppWindow :
	public ATL::CWindow
{
public:
	CNppWindow(HWND hNppWnd)
	{
		m_hWnd = hNppWnd;
		ATL_CHECK_HWND(m_hWnd);
	}

	CNppWindow(const NppData& nppData)
	{
		m_hWnd = nppData._nppHandle;
		ATL_CHECK_HWND(m_hWnd);
	}

public:
	// Create a new file
	void FileNew()
	{
		SendMessage(NPPM_MENUCOMMAND, 0, IDM_FILE_NEW);
	}

	void FileClose()
	{
		SendMessage(NPPM_MENUCOMMAND, 0, IDM_FILE_CLOSE);
	}

	void EditSetReadonly()
	{
		SendMessage(NPPM_MENUCOMMAND, 0, IDM_EDIT_SETREADONLY);
	}

	void DoOpen(const CString& filepath)
	{
		SendMessage(NPPM_DOOPEN,0,(WPARAM)(LPCTSTR)filepath);
	}

	void Reload()
	{
		SendMessage(NPPM_MENUCOMMAND, 0, IDM_FILE_RELOAD);
	}

	void SetCurrentLangType(LangType langType)
	{
		SendMessage(NPPM_SETCURRENTLANGTYPE,0,(LPARAM)langType);
	}

	void SetCurrentLang(int idm_lang)
	{
		ATLASSERT(IDM_LANG<idm_lang && idm_lang<IDM_LANG_USER_LIMIT);
		SendMessage(NPPM_MENUCOMMAND, 0, idm_lang);
	}

	//
	int GetCurrentDocIndex()
	{
		return SendMessage(NPPM_GETCURRENTDOCINDEX,0,MAIN_VIEW);
	}

	void ActiveDoc(int index2Activate)
	{
		SendMessage(NPPM_ACTIVATEDOC,0,index2Activate);
	}
};